package com.annotation_for_java;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

/**
 * @ClassName: DemoClass
 * @Author: ZhangYue26
 * @Description: 注解只能以反射的方式去验证参数或者方法的有效性，这里给出了一个简单的示例
 * @Date: 2020-11-02
 */
public class DemoClass {

    @ValueAnnotation(min = 0, max = 100)
    private int num = 10;

    @MethodAnnotation(methodReturn = String.class,methodParams = 1)
    public String getNumString(int num) {
        num = this.num;
        return String.valueOf(num);
    }

    public static void main(String[] args) throws Exception {
        DemoClass demoClass = new DemoClass();
        Class<? extends DemoClass> demo = demoClass.getClass();
        Method[] methods = demo.getDeclaredMethods();
        for (Method method : methods) {
            MethodAnnotation annotation = method.getAnnotation(MethodAnnotation.class);
            if (annotation!=null){
                Class<?> methodReturn = annotation.methodReturn();
                if (method.getReturnType() != methodReturn)
                    throw new Exception("方法返回值与注解定义的返回值不一致");
                int methodParamsNum = annotation.methodParams();
                if (methodParamsNum !=method.getParameterCount())
                    throw new Exception("参数数量不一致");
            }
        }
        Field[] declaredFields = demo.getDeclaredFields();
        for (Field field : declaredFields) {
            ValueAnnotation annotation = field.getAnnotation(ValueAnnotation.class);
            if (annotation != null) {
                Type genericType = field.getGenericType();
                if (genericType.getTypeName().equals("int")) {//int类型
                    int min = annotation.min();
                    int max = annotation.max();
                    if (!(field.getInt(demoClass) >= min && field.getInt(demoClass) <= max)) {
                        throw new Exception("该成员变量值已经超出了范围");
                    }
                } else {
                    throw new Exception("该注解应该用在int类型的成员变量上");
                }
            }
        }

    }
}
